package com.zy.design.pattern.decorator;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author zhaoyi
 * @date 2021/4/9 15:48
 * <p>
 * 装饰器模式
 * <p>
 * 第一 装饰器类和原始类继承同样的父类，这样我们可以对原始类“嵌套”多个装饰器类。
 * 第二 装饰器类是对功能的增强(而代理模式中，代理类附加的是跟原始类无关的功能)
 * 代理模式		调用端无感知.
 * 装饰器模式	调用有感知主动选择
 * <p>
 * BufferedInputStream和DataInputStream等为什么不直接继承InputStream而通过FilterInputStream间接继承?
 * 对于即便是不需要增加缓存功能的函数来说，BufferedInputStream 还是必须把它重新实现一遍，简单包裹对 InputStream 对象的函数调用。
 * 如果不包裹就是当前对象, 无法将最终读取数据的任务，委托给传递进来的InputStream 对象来完成。
 * 为了避免代码重复把包裹的代码抽象出了一个装饰器父类 FilterInputStream
 */
public class TestDecorator {

    public static void main(String[] args) throws IOException {

        /**
         * 我们对 FileInputStream 嵌套了两个装饰器类：BufferedInputStream 和 DataInputStream，
         * 让它既支持缓存读取，又支持按照基本数据类型来读取数据。
         */
        InputStream in = TestDecorator.class.getResourceAsStream("/dec");
        InputStream bin = new BufferedInputStream(in);
        DataInputStream din = new DataInputStream(bin);
        int data = din.readInt();
        System.out.println(data);

        /**
         * 装饰器 示例-----
         * 我添加了自动驾驶的功能
         * 我添加了新的动力系统 超级混动
         * 开着我上路吧!!!
         */
        //普通的汽油车
        GasolineCar gasolineCar = new GasolineCar();
        //装饰器-增强-新能源
        ADecoratorCarByNewEnergy newEnergy = new ADecoratorCarByNewEnergy(gasolineCar);
        //装饰器-增强-自动驾驶
        ICar car = new ADecoratorCarByAutomatic(newEnergy);
        car.drive();



    }

}
